package com.qk.management.aop;

import cn.hutool.json.JSONUtil;
import com.qk.common.Result;
import com.qk.common.enums.AOPEnum;
import com.qk.management.aop.anno.Cacheable;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;

/**
 * @author: zyx
 * @created: 2025-10-17-11:52
 * @description:
 */
@Aspect
@Component
@Slf4j
public class RedisCacheAspect {
    @Autowired
    private StringRedisTemplate redisClient;



    @Around("@annotation(com.qk.management.aop.anno.Cacheable)")
    public Object around(ProceedingJoinPoint pjp)  {
        String redisKey = null;
        long expire= 0L;
        TimeUnit timeUnit = null;
        try {
            //从注解获取信息
            Class<?> targetClass = pjp.getTarget().getClass();
            String methodName = pjp.getSignature().getName();
            Method method = targetClass.getMethod(methodName);
            Cacheable annotation = method.getAnnotation(Cacheable.class);
            String prefix = annotation.keyPrefix();
            redisKey = prefix + methodName;
            expire = annotation.expire();
            timeUnit = annotation.timeUnit();
            if(redisClient.hasKey(redisKey)) {
                // 缓存命中将缓存数据转成对象返回
                String jsonStr = redisClient.opsForValue().get(redisKey);
                return JSONUtil.toBean(jsonStr,method.getReturnType());

            }
        } catch (Exception e) {
            log.error("查询缓存异常",e);
        }
        // 缓存未命中
        Object returnValue = null;
        try {
            returnValue = pjp.proceed();
        } catch (Throwable e) {
            return Result.error(AOPEnum.OPERATION_FAILED.getMsg());
        }
        try {
            redisClient.opsForValue().set(redisKey, JSONUtil.toJsonStr(returnValue), expire, timeUnit);
        } catch (Exception e) {
            log.error("添加缓存异常",e);
        }
        return returnValue;
    }
};
